(module data scheme

;; This line tells scheme to provide everything in this file to anyone who requires it.
(provide (all-defined-out))

;; we need world.ss for check-expect, etc.
(require (lib "world.ss" "teachpack" "htdp"))
(require lang/htdp-intermediate-lambda)

;; This file provides data accessors for the data provided by the server. It contains the
;; necessary creators, accessors, and predicates to use the the data provided by the server
;; as though it WERE a scheme struct. This can go a long way toward making code more
;; readable and accessible. Sample data is also provided.

;; WE CANNOT USE DEFINE-STRUCT IN THE UNIVERSE.
;; This is because structs are not s-expressions.
;;(define-struct board (territories continents players state))

;; A Board is a (make-board [ListOf Territory]
;;                          [Listof Continent]
;;                          [Listof Player]
;;                          State
;; Where territories is a list of territories on the game board
;;       continents is a list of continents on the game board
;;       players is a list of players on the game board
;;       state is the current state information of the game board


  
(define (territory-widget t) (sixth t))
;; FUNCTIONS WE SHOULD HAVE FROM (define-struct board ...)
(define (make-board territories continents players state)
  (list territories continents players state))

(define (board-territories board)
  (first board))

(define (board-continents board)
  (second board))

(define (board-players board)
  (third board))

(define (board-state board)
  (fourth board))

(define (board? board)
  (and (list? board)
       (= (length board) 4)))

;; A State is a 3 (THREE) element list:
;; the first element is a symbol representing the state
;;; either:
;;; 'init
;;; 'p1
;;; 'p2-origin
;;; 'p2-victim
;;; 'p3-origin
;;; 'p3-dest

;; the second and third elements are extra data about the state.

;;; p1:
;;; - (list symbol number empty)
;; the number is the number of units remaining that can be placed
;; the remaining two fields are unused.

;;; p2-origin
;;; - (list symbol empty empty)
;; there is no data to be stored here other than ui-elements and the symbol
;; representing the current phase.

;;; p2-victim
;;; - (list symbol Territory empty)
;; We store the territory that the person is attacking from and attempt to
;; determine what territory that they are attacking using that data.

;;; p3-origin
;;; - (list symbol empty empty)
;; we store nothing here besides the phase and ui-elements that can be manipulated
;; on the screen. The player will click a territory that they want to draw
;; reenforcements from, or go to the next phase.

;;; p3-destination
;;; - (list symbol Territory Number)
;; we store the territory that the player has chosen to draw reenforcments from
;; and the number of units that are remaining to be placed. We need to be able
;; to draw a line from the originating territory to the reenforced one, so
;; we need both to find the path.

;; What's this last list of ui-element doing? I'm doing reinforcement via neighbors, also
;; something that is in the territory struct itself.

;;(define-struct territory (name continent units neighbors player widget))
;; A Territory is a:
;; (make-territory Symbol Symbol Number [ListOf Symbol] Symbol Widget)
;; where name is the name of the territory
;;       units is the number of men in the territory
;;       neighbors is the list off all territories bordering this territory
;;       player is the player who controls this territory
(define (make-territory name continent units neighbors player)
  (list name continent units neighbors player))

;; Accessor methods for a territory
(define (territory-name territory)
  (first territory))
(define (territory-continent territory)
  (second territory))
(define (territory-units territory)
  (third territory))
(define (territory-neighbors territory)
  (fourth territory))
(define (territory-player territory)
  (fifth territory))
  
;; Predicate for a territory - is the given thing a territory?
(define (territory? territory)
  (and (list? territory)
       (= (length territory) 5)))


;;(define-struct continent (name value))
;; A Continent is a (make-continent symbol number)
;; name – a symbol representing the name of the continent
;; value – the number of reenforcements a player receives for owning this continent
(define (make-continent name value)
  (list name value))

;; Accessor methods for continents
(define (continent-name continent)
  (first continent))
(define (continent-value continent)
  (second continent))
(define (continent? continent)
  (and (list? continent)
       (= (length continent) 2)))

#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|#
;; SAMPLE DATA FOR TESTING PURPOSES:


;;;; SAMPLE CONTINENTS ;;;;

;; mini-asia
(define mini-asia (make-continent 'asia 2))
;; mini-europe
(define mini-europe (make-continent 'europe 3))
;; mini-america
(define mini-america (make-continent 'america 2))

(define continent-list (list mini-asia mini-europe mini-america))


;;;; ADJCENCY LISTS FOR TERRITORIES ;;;;

;; mini-america lists
(define adj-canada '(usa france))
(define adj-usa    '(canada mexico china))
(define adj-mexico '(usa sa))
(define adj-sa     '(mexico africa-north))

;; mini-europe lists
(define adj-france       '(canada germany mideast))
(define adj-germany      '(france mideast russia))
(define adj-mideast      '(germany africa-north france))
(define adj-africa-north '(mideast africa-south sa))
(define adj-africa-south '(africa-north))

;; mini-asia lists
(define adj-russia    '(germany china))
(define adj-china     '(russia australia usa))
(define adj-australia '(china))


;;
;; @territories
;; The normal territories
;;;;;;;;;;;;;;;

;; american territories
(define ter-canada (make-territory 'canada 'america 0 adj-canada 'unowned))
(define ter-usa    (make-territory 'usa 'america 0 adj-usa 'unowned))
(define ter-mexico (make-territory 'mexico 'america 0 adj-mexico 'unowned))
(define ter-sa     (make-territory 'sa 'america 0 adj-sa 'unowned))

;; european territories
(define ter-france       (make-territory 'france 'europe 0 adj-france 'unowned))
(define ter-germany      (make-territory 'germany 'europe 0 adj-germany 'unowned))
(define ter-mideast      (make-territory 'mideast 'europe 0 adj-mideast 'unowned))
(define ter-africa-north (make-territory 'africa-north 'europe 0 adj-africa-north 'unowned))
(define ter-africa-south (make-territory 'africa-south 'europe 0 adj-africa-south 'unowned))

;; asian territories
(define ter-russia    (make-territory 'russia 'asia 0 adj-russia 'unowned))
(define ter-china     (make-territory 'china 'asia 0 adj-china 'unowned))
(define ter-australia (make-territory 'australia 'asia 0 adj-australia 'unowned))

;; THE STARTING TERRITORY LIST:
(define territory-list-base
  (list ter-canada ter-usa ter-mexico ter-sa ter-france ter-germany ter-mideast
        ter-africa-north ter-africa-south ter-russia ter-china ter-australia))

;; A Test territory list, for testing
(define test-ter-list
  (list ter-canada ter-usa))

;; A Dummy canada
(define fake-canada (make-territory 'canada 0 0 0 0))

;; A Fake Board for Testing
(define ter-update-board (make-board test-ter-list empty empty (list 'p1 10 empty)))

;; An updated america
(define ter-usa-plus1    (make-territory 'usa 'america 1 adj-usa 'unowned))

;; An updated canasa
(define ter-canada-plus1 (make-territory 'canada 'america 1 adj-canada 'unowned))

;;
;; @gplayers
;; The g- prefixed players
;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Players will be handed colors in the order listed here.
(define g-players '(red blue))

;;
;; END OF
;; The g- prefixed players
;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;; @gterritoriers
;; The g- prefixed territoriers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; american territories
(define g-ter-canada (make-territory 'canada 'america 8 adj-canada 'blue))
(define g-ter-usa    (make-territory 'usa    'america 3 adj-usa    'blue))
(define g-ter-mexico (make-territory 'mexico 'america 7 adj-mexico 'blue))
(define g-ter-sa     (make-territory 'sa     'america 7 adj-sa     'red))

;; european territories
(define g-ter-france       (make-territory 'france       'europe 4 adj-france       'red))
(define g-ter-germany      (make-territory 'germany      'europe 4 adj-germany      'red))
(define g-ter-mideast      (make-territory 'mideast      'europe 3 adj-mideast      'red))
(define g-ter-africa-north (make-territory 'africa-north 'europe 5 adj-africa-north 'blue))
(define g-ter-africa-south (make-territory 'africa-south 'europe 2 adj-africa-south 'blue))

;; asian territories
(define g-ter-russia    (make-territory 'russia    'asia 9 adj-russia    'red))
(define g-ter-china     (make-territory 'china     'asia 4 adj-china     'red))
(define g-ter-australia (make-territory 'australia 'asia 1 adj-australia 'red))

;; the list of territores AT THIS POINT in our game
(define g-territory-list-current
  (list g-ter-canada g-ter-usa g-ter-mexico g-ter-sa g-ter-france g-ter-germany g-ter-mideast
        g-ter-africa-north g-ter-africa-south g-ter-russia g-ter-china g-ter-australia))
;;
;; END OF
;; The g- prefixed territories
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;; @gstates
;; The g- prefixed states
;;;;;;;;;;;;;;;;;;;;;;;;;;
(define g-state-p1 (list 'p1 10 empty))
(define g-state-p2-o (list 'p2-origin empty empty))
(define g-state-p2-victim-germany-blue (list 'p2-victim
                                            g-ter-germany
                                            empty))
(define g-state-p3-o (list 'p3-origin empty empty))
(define g-state-p3-d (list 'p3-dest ter-canada 0))

;; used for the new state machine implementation of attacking
(define g-state-p2-from (list 'p2-origin empty empty))
(define g-state-p2-to (list 'p2-victim
                            (list g-ter-germany)
                            empty))
(define g-state-p2-commence-attack (list 'p2-victim
                                         (list g-ter-germany g-ter-france)
                                         'commence-attack))
(define g-state-p2-continue? (list 'p2-victim
                                   (list g-ter-germany g-ter-france)
                                   'continue?))

;;
;; END OF
;; The g- prefixed states
;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;; @boards
;; Board data that is used for testing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define board-blank (make-board territory-list-base
                                continent-list
                                g-players
                                g-state-p1))
(define g-board-p1 (make-board g-territory-list-current
                               continent-list
                               g-players
                               g-state-p1))
(define board-blank-state2 (make-board territory-list-base
                                       continent-list
                                       g-players
                                       g-state-p2-o))
(define board-blank-player-blue (make-board territory-list-base
                                            continent-list
                                            `(blue red)
                                            g-state-p2-o))
(define running-game-p2-o (make-board g-territory-list-current
                                      continent-list
                                      g-players
                                      g-state-p2-o))
(define running-game-p2-victim (make-board g-territory-list-current
                                           continent-list
                                           g-players
                                           g-state-p2-victim-germany-blue))
;; used in testing the new attack functions
(define test-board-p2-from (make-board g-territory-list-current
                                       continent-list
                                       g-players
                                       g-state-p2-from))
(define test-board-p2-to (make-board g-territory-list-current
                                     continent-list
                                     g-players
                                     g-state-p2-to))
(define test-board-p2-commence-attack (make-board g-territory-list-current
                                       continent-list
                                       g-players
                                       g-state-p2-commence-attack))
(define test-board-p2-continue? (make-board g-territory-list-current
                                            continent-list
                                            g-players
                                            g-state-p2-continue?))

(define running-game-p3-o (make-board g-territory-list-current
                                      continent-list
                                      g-players
                                      g-state-p3-o))
(define running-game-p3-d-0 (make-board g-territory-list-current
                                      continent-list
                                      g-players
                                      g-state-p3-d))
;;
;; END OF
;; Board data that is used for testing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;; phase 2 Attack Defend Test Data
(define g-ter-canada-post-attack (make-territory 'canada 'america 1 adj-canada 'blue))
(define g-ter-usa-post-attack    (make-territory 'usa    'america 7 adj-usa    'blue))

(define g-ter-mideast-post-attack      (make-territory 'mideast      'europe 4 adj-mideast      'red))
(define g-ter-africa-north-post-attack (make-territory 'africa-north 'europe 1 adj-africa-north 'blue))

) ;; end of module
